﻿// WarframeAlert displays recent alerts from the WarframeAlerts Twitter feed.
// Copyright (C) 2013  Jeff Siebold aka NoonKnight
// Find updates of this program at <http://noonknight.com/WarframeAlert/>.
// Please send email to <noonknight@gmail.com> with WarframeAlert in the subject.

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//#define BETA

using System;
using System.Deployment.Application;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace WarframeAlert
{
	static class WarframeAlert
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>

		private static readonly Assembly assembly = Assembly.GetExecutingAssembly();
		public static readonly String Name = assembly.GetName().Name;
		// get application GUID as defined in AssemblyInfo.cs
		private static readonly String guid = ((GuidAttribute)assembly.
			GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();

		private const int HWND_BROADCAST = 0xffff;
		private static readonly String WndMsgShowMe = "WM_SHOW_" + guid.Replace('-', '_');
		public static readonly int WM_SHOWME = RegisterWindowMessage(WndMsgShowMe);

		[DllImport("user32")]
		public static extern bool PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam);

		[DllImport("user32")]
		public static extern int RegisterWindowMessage(String message);

		[STAThread]
		static void Main()
		{
			using (var mutex = new Mutex(false, "{" + guid + "}"))
			{
				var hasHandle = false;
				try
				{
					try
					{
						hasHandle = mutex.WaitOne(0, false);
						if (!hasHandle)
						{
							PostMessage((IntPtr)HWND_BROADCAST, WM_SHOWME, IntPtr.Zero, IntPtr.Zero);
							return;
						}
					}
					catch (AbandonedMutexException)
					{
						// Log the fact the mutex was abandoned in another process, it will still get aquired
						hasHandle = true;
					}

					UpdateIfNeeded();

					Application.EnableVisualStyles();
					Application.SetCompatibleTextRenderingDefault(false);
					Application.Run(new WaForm());
				}
				finally
				{
					if (hasHandle)
						mutex.ReleaseMutex();
				}
			}
		}

		private static void UpdateIfNeeded()
		{
			// http://bloggingabout.net/blogs/dennis/archive/2007/11/05/manual-check-for-updates-with-clickonce.aspx
			if (!ApplicationDeployment.IsNetworkDeployed)
				return;

			ApplicationDeployment currDeployment = ApplicationDeployment.CurrentDeployment;
			UpdateCheckInfo updateInfo = currDeployment.CheckForDetailedUpdate();
			if (!updateInfo.UpdateAvailable)
				return;

			if (updateInfo.IsUpdateRequired)
			{
				MessageBox.Show(
					Name + " has a REQUIRED update available and will be installed now.",
					Name, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			}
			else
			{
				DialogResult dialogResult = MessageBox.Show(
					"An update to " + Name + " is available. Would you like to install it now?",
					Name, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
				if (dialogResult != DialogResult.Yes)
					return;
			}
 
			try
			{
				currDeployment.Update();
				MessageBox.Show(
					"\"" + Name + "\" has been upgraded and will now restart",
					Name, MessageBoxButtons.OK, MessageBoxIcon.Information);
				Application.Restart();
			}
			catch (DeploymentDownloadException dde)
			{
				MessageBox.Show(
					"Cannot install the latest version of " + Name + ".\n\n" +
					"Please check your network connection and try again later.\n\n" +
					"Error: " + dde,
					Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
		}
	}

	public static class HelperExtensions
	{
		public static TimeSpan Round(this TimeSpan time, TimeSpan roundingInterval, MidpointRounding roundingType)
		{
			return new TimeSpan(
				Convert.ToInt64(Math.Round(
					time.Ticks / (decimal)roundingInterval.Ticks,
					roundingType
				)) * roundingInterval.Ticks
			);
		}

		public static TimeSpan Round(this TimeSpan time, TimeSpan roundingInterval)
		{
			return Round(time, roundingInterval, MidpointRounding.ToEven);
		}

		public static DateTime Round(this DateTime datetime, TimeSpan roundingInterval)
		{
			return new DateTime((datetime - DateTime.MinValue).Round(roundingInterval).Ticks);
		}
	}
}
